#pragma once
#include <iostream>
#include <memory>
#include "Socket.hpp"
#include <pthread.h>
#include <functional>
using namespace std;
using task_t = function<void(Socket*)>;
class TcpServer;

struct ThreadData {
    ThreadData(TcpServer* tcp_this, Socket* sockp) 
        :_this(tcp_this)
        ,_sockp(sockp)
    {}
    TcpServer* _this;
    Socket* _sockp;
};

class TcpServer {
public :
    TcpServer(uint16_t port, task_t handler_request) 
        :_port(port)
        ,_handler_request(handler_request)
        ,_listensocket(new TcpSocket)
    {
        _listensocket->BuildListenSocketMethod(_port, default_backlog);
    }

    static void* ThreadRoutine(void* args) {
        // 将本线程设置成分离状态
        pthread_detach(pthread_self());
        ThreadData* td = static_cast<ThreadData*>(args);
        td->_this->_handler_request(td->_sockp);

        td->_sockp->CloseSockFd();
        delete td->_sockp;
        delete td;
    }

    void Loop() {
        // 获取新链接
        while (true) {
            string peerip;
            uint16_t peerport;
            Socket* newsocket = _listensocket->AcceptSocket(&peerip, &peerport);
            if (newsocket) {
                cout << "get a new connect newsockfd: " << newsocket->GetSockFd() << endl;
            } else {
                continue;
            }
            // 创建线程处理连接
            pthread_t tid;
            ThreadData* td = new ThreadData(this, newsocket);
            pthread_create(&tid, nullptr, ThreadRoutine, td);

        }
        
    }

    ~TcpServer() {

    }

private :
    uint16_t _port;
    Socket* _listensocket;
    task_t _handler_request;
};